package com.fary.web.servlet.config.annotation;

import com.fary.format.FormatterRegistry;
import com.fary.http.converter.HttpMessageConverter;
import com.fary.validation.MessageCodesResolver;
import com.fary.validation.Validator;
import com.fary.web.method.support.HandlerMethodArgumentResolver;
import com.fary.web.method.support.HandlerMethodReturnValueHandler;
import com.fary.web.servlet.HandlerExceptionResolver;

import java.util.List;

public interface WebMvcConfigurer {

	/**
	 * 1.ServletMappings 设置的是 "/"
	 * 2.setUseSuffixPatternMatch默认设置为true,
	 * 那么/user 就会匹配 /user.*,也就是说,/user.html 的请求会被 /user 的 Controller所拦截.
	 * 3.如果该值为false,则不匹配
	 * configurer.setUseSuffixPatternMatch(false);
	 *
	 * setUseTrailingSlashMatch的默认值为true
	 * 也就是说, "/user" 和 "/user/" 都会匹配到 "/user"的Controller
	 * configurer.setUseTrailingSlashMatch(true);
	 */
	default void configurePathMatch(PathMatchConfigurer configurer) {
	}

	/**
	 * 内容协商
	 */
	default void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
	}

	/**
	 * 异步处理的配置，设置超时、异步任务执行器
	 */
	default void configureAsyncSupport(AsyncSupportConfigurer configurer) {
	}

	/**
	 * 开启对静态资源的访问
	 */
	default void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
	}

	/**
	 * Spring MVC提供了几个格式化类：DateFormatter、NumberFormatter、CurrencyFormatter、PercentFormatter
	 * 利用注解@NumberFormat和@DateTimeFormat，注释在实体类的实例变量上，也可以实现日期、时间、数字的格式化
	 */
	default void addFormatters(FormatterRegistry registry) {
	}

	/**
	 * 添加拦截器
	 */
	default void addInterceptors(InterceptorRegistry registry) {
	}

	/**
	 * 添加处理程序以从 Web 应用程序根目录、类路径等的特定位置提供静态资源，例如图像、js 和 css 文件。
	 */
	default void addResourceHandlers(ResourceHandlerRegistry registry) {
	}

	/**
	 * 配置允许跨域访问的路径
	 */
	default void addCorsMappings(CorsRegistry registry) {
	}

	/**
	 * 实现无业务逻辑跳转
	 */
	default void addViewControllers(ViewControllerRegistry registry) {
	}

	/**
	 * 配置视图解析器以将从控制器返回的基于字符串的视图名称转换为具体的视图 实现以执行渲染。
	 */
	default void configureViewResolvers(ViewResolverRegistry registry) {
	}

	/**
	 * 添加解析器以支持自定义控制器方法参数类型。
	 * 这不会覆盖对解析处理程序方法参数的内置支持。
	 * 要自定义对参数解析的内置支持，请直接配置 RequestMappingHandlerAdapter
	 */
	default void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
	}

	/**
	 * 添加处理程序以支持自定义控制器方法返回值类型。
	 * 使用此选项不会覆盖对处理返回值的内置支持。
	 * 要自定义处理返回值的内置支持，请直接配置 RequestMappingHandlerAdapter。
	 */
	default void addReturnValueHandlers(List<HandlerMethodReturnValueHandler> handlers) {
	}

	/**
	 * 配置 HttpMessageConverters 以用于读取或写入请求或响应的正文。
	 * 如果没有添加转换器，则会注册一个默认的转换器列表。 将转换器添加到列表会关闭默认转换器注册。
	 * 要在不影响默认注册的情况下简单地添加转换器，请考虑改用 {extendMessageConverters} 方法。
	 */
	default void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
	}

	/**
	 * 配置后用于扩展或修改转换器列表的挂钩。这可能很有用，例如允许注册默认转换器，然后通过此方法插入自定义转换器。
	 */
	default void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
	}

	/**
	 * 配置异常解析器。
	 * 给定的列表一开始是空的。如果它留空，框架会配置一组默认的解析器，
	 * 请参阅 {@link WebMvcConfigurationSupport#addDefaultHandlerExceptionResolvers(List)}。
	 * 或者，如果将任何异常解析器添加到列表中，则应用程序有效地接管并且必须提供完全初始化的异常解析器。
	 * 您也可以使用 {extendHandlerExceptionResolvers(List)} 来扩展或修改默认配置的异常解析器列表。
	 * @see WebMvcConfigurationSupport#addDefaultHandlerExceptionResolvers(List)
	 */
	default void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> resolvers) {
	}

	/**
	 * 扩展或修改默认配置的异常解析器列表。这对于插入自定义异常解析器而不干扰默认异常解析器很有用。
	 * @see WebMvcConfigurationSupport#addDefaultHandlerExceptionResolvers(List)
	 */
	default void extendHandlerExceptionResolvers(List<HandlerExceptionResolver> resolvers) {
	}

	/**
	 * Provide a custom {@link Validator} instead of the one created by default.
	 * The default implementation, assuming JSR-303 is on the classpath, is:
	 * {@link org.springframework.validation.beanvalidation.OptionalValidatorFactoryBean}.
	 * Leave the return value as {@code null} to keep the default.
	 */
	default Validator getValidator() {
		return null;
	}

	/**
	 * Provide a custom {@link MessageCodesResolver} for building message codes
	 * from data binding and validation error codes. Leave the return value as
	 * {@code null} to keep the default.
	 */
	default MessageCodesResolver getMessageCodesResolver() {
		return null;
	}

}